/*
 * PWF - Prototype Widget framework, version 0.1
 * (c) 2008 David Lindkvist
 * 
 * PWF is freely distributable under the terms of an MIT-style license.
 * For details, see the project web site: http://code.google.com/p/prototype-widget-framework/
 */


PWF={version:'0.1',defaultHtmlTemplate:'template.html',defaultCssTemplate:'template.css'};PWF.mixin={};var Log={toggle:function(){},move:function(){},resize:function(){},clear:function(){},debug:function(){},info:function(){},warn:function(){},error:function(){},profile:function(){}};PWF.enableLogging=function()
{var ScriptPath=Class.create(PWF.mixin.ScriptPath);var scriptPath=new ScriptPath();var path=scriptPath.getScriptPath('pwf-'+PWF.version);PWF.mixin.DOMUtils.loadStyleSheet(path+'logging/blackbird.css');PWF.mixin.DOMUtils.loadJavaScript(path+'logging/blackbird.js');};PWF.create=function()
{var name=arguments[0];if(!Object.isString(name)){throw'No class name was supplied!';}
var strArgs='';for(var i=1;i<arguments.length;i++)
{if(i>1){strArgs+=',';}
strArgs+='arguments['+i+']';}
var theClass=eval('Class.create('+strArgs+');');theClass.addMethods({getName:function(){return name;}});eval(name+"=theClass");};PWF.loginHandler=function(successCallback)
{};PWF.loginHandlerInProgress=false;

PWF.mixin.DOMUtils={loadStyleSheet:function(src)
{var css=new Element('link',{'rel':'stylesheet','href':src,'type':'text/css','media':'all'});document.getElementsByTagName('head')[0].appendChild(css);},loadJavaScript:function(src)
{var script=new Element('script',{'src':src,'type':'text/javascript'});document.getElementsByTagName('head')[0].appendChild(script);}};

PWF.mixin.ScriptPath={getScriptPath:function(scriptFileName)
{var scripts=this.getScriptsByName(scriptFileName);var myScript=scripts[0];if(myScript)
{var myReg=new RegExp(scriptFileName+".js$","g");var path=myScript.src.replace(myReg,'');return path;}
return"/";},getScriptsByName:function(scriptFileName)
{var scripts=$A(document.getElementsByTagName("script")).findAll(function(s)
{var myReg=new RegExp(scriptFileName+".js$","g");return(s.src&&s.src.match(myReg));});return scripts;}};

PWF.mixin.LoadingAnimation={showLoadingAnimation:function(opacity)
{this.hideLoadingAnimation();if(Object.isUndefined(opacity)){opacity=0.2;}
var container=$(this.containerId);this.splash=new Element('div');var imgY=(this.height/2)-25;var imgX=(this.width/2)-25;var top=0;var left=0;if(container.getStyle('position')!='absolute')
{top=container.cumulativeOffset().top;left=container.cumulativeOffset().left;}
this.splash.setStyle({height:container.getHeight()+'px',width:container.getWidth()+'px',opacity:opacity,position:'absolute',left:left+'px',top:top+'px'});container.insert(this.splash);this.splash.addClassName('widgetLoadingAnimation');},hideLoadingAnimation:function()
{if(!Object.isUndefined(this.splash))
{try{this.splash.remove();}
catch(ex){}
this.splash=undefined;}}};

PWF.mixin.AjaxContentLoader={loadContent:function(containerId,sourceUrl){$(containerId).update('');this.onLoadInit();new Ajax.Updater(containerId,sourceUrl,{method:'get',onComplete:this.onLoadSuccess.bind(this),onException:this.onLoadError.bind(this)});},onLoadInit:function(){},onLoadSuccess:function(){},onLoadError:function(){}};

PWF.mixin.AjaxRequest={callAction:function(actionUrl,method)
{this.onRequestInit();if(method===undefined||method===null)
method='post';var debugParams=this.actionParams?this.actionParams.toQueryString():'';Log.debug('callAction: '+actionUrl+' ('+method+') params:'+debugParams);new Ajax.Request(this.actionUrl,{method:method,parameters:this.actionParams,requestHeaders:{Accept:'application/json'},onSuccess:this.onRequestSuccess.bind(this),onFailure:this.onRequestFailure.bind(this),onException:this.onRequestException.bind(this)});},onRequestInit:function()
{},onRequestSuccess:function(transport)
{},onRequestFailure:function(transport)
{},onRequestException:function(request)
{},addParameter:function(key,value)
{if(this.actionParams===undefined||this.actionParams===null)
{this.actionParams=new Hash();}
this.actionParams.set(key,value);},clearParameters:function()
{this.actionParams=null;}};

PWF.Action=Class.create(PWF.mixin.AjaxRequest,{initialize:function(actionUrl,callbackInit,callbackSuccess,callbackFailure,method)
{this.actionUrl=actionUrl;this.callbackInit=callbackInit;this.callbackSuccess=callbackSuccess;this.callbackFailure=callbackFailure;this.method=method;},run:function()
{this.callbackInit();this.callAction(this.actionUrl,this.method);},onRequestSuccess:function(transport)
{var json=transport.responseText.evalJSON();if(json.outcome==1)
{Log.debug('action outcome: success');this.callbackSuccess(json);}
else if(json.outcome==-1)
{Log.debug('action outcome: failed ('+json.errorMsg+')');this.callbackFailure(json.errorMsg,json)}
else if(json.outcome==-2)
{Log.debug('action outcome: invalid session');this.callbackFailure('Kunde inte utföra åtgärden - ej inloggad');if(!PWF.loginHandlerInProgress)
{Log.debug('action login required - calling PWF.loginHandler()');PWF.loginHandlerInProgress=true;PWF.loginHandler(this.loginHandlerSuccess.bind(this));}}},loginHandlerSuccess:function()
{Log.debug('action login success - re-running action');PWF.loginHandlerInProgress=false;this.run();},onRequestFailure:function(request)
{Log.error('action failure: '+request.status);this.callbackFailure('Ett fel har uppstått, var god försök igen (e)');},onRequestException:function(request,ex)
{Log.error('action exception: '+request.status+', '+ex);this.callbackFailure('Ett fel har uppstått, var god försök igen (x)');}});

PWF.create('PWF.Widget',PWF.mixin.DOMUtils,PWF.mixin.ScriptPath,PWF.mixin.AjaxContentLoader,PWF.mixin.LoadingAnimation,{initialize:function(containerId)
{Log.info('creating instance of '+this.getName());this.containerId=containerId;this.container=$(containerId);this.baseName='pwf-'+PWF.version;this.coreCSS='loading.css';this.loadingImage='loading.gif';this.loadingStyleClass='widgetLoading';this.loadErrorStyleClass='widgetLoadError';this.templateHtml=PWF.defaultHtmlTemplate;this.templateCSS=PWF.defaultCssTemplate;this.width==undefined;this.height==undefined;this.msgLoadError='Nätverksproblem. Modulen kunde ej laddas.';this.msgLoadErrorRetry='Försök igen';this.init();this.loadWidget();},getLoadingImageUrl:function()
{return this.getScriptPath(this.baseName)+this.loadingImage;},loadWidget:function()
{Log.profile(this.getName()+' - load widget');var coreCSSUrl=this.getScriptPath(this.baseName)+this.coreCSS;this.loadStyleSheet(coreCSSUrl);var templateCSSUrl=this.getTemplateUrl(this.templateCSS);this.loadStyleSheet(templateCSSUrl);this.loadTemplate();},onLoadInit:function()
{this.container.addClassName(this.loadingStyleClass);this.adjustWidgetSize();this.showLoadingAnimation();},onLoadSuccess:function()
{Log.info(this.getName()+' - template file loaded OK');$(this.containerId).firstDescendant().hide();new Effect.Appear($(this.containerId).firstDescendant(),{duration:0.3});this.widgetLoaded();this.container.removeClassName(this.loadingStyleClass);Log.profile(this.getName()+' - load widget');},onLoadError:function(request,exception)
{Log.error(this.getName()+' - load widget failed: '+exception);this.container.removeClassName(this.loadingStyleClass);this.hideLoadingAnimation();var pErrorMsg=new Element('p').update(this.msgLoadError);this.container.update(pErrorMsg);this.container.addClassName(this.loadErrorStyleClass);var retryLink=new Element('a',{'href':'#'}).update(this.msgLoadErrorRetry);retryLink.observe('click',this.reloadListener.bindAsEventListener(this));var pRetry=new Element('p').update(retryLink);this.container.insert(pRetry);},reloadListener:function(e)
{Log.info(this.getName()+' - user retrying load of template');this.container.update('');this.container.classNames().each(function(n){container.removeClassName(n);});this.loadWidget();},widgetLoaded:function()
{Log.warn(this.getName()+' - method widgetLoaded is not implemented');throw"method widgetLoaded must be implemented in subclass!";},init:function()
{},adjustWidgetSize:function()
{if(this.width!==undefined)
{this.container.setStyle({width:this.width+'px'});}
if(this.height!==undefined)
{this.container.setStyle({height:this.height+'px'});}},loadTemplate:function(templateName,loadCallback)
{if(templateName===undefined)
templateName=this.templateHtml;if(loadCallback!==undefined)
this.widgetLoaded=loadCallback;var templateUrl=this.getTemplateUrl(templateName);Log.debug(this.getName()+' - loadTemplate('+templateName+'): url='+templateUrl);this.loadContent(this.container.id,templateUrl);},getElement:function(elementId)
{var element=$(elementId);if(Object.isUndefined(element))
{Log.warn(this.getName+' - getElement('+elementId+'): element does not exist');return null;}
element.id=this.containerId+'_'+element.id;return element;},getWidgetUrl:function()
{return this.getScriptPath(this.getName());},getTemplateUrl:function(templateName)
{return this.getWidgetUrl()+templateName;},getViewUrl:function(viewName)
{return this.getWidgetUrl()+'../../views/'+viewName;},redirectToView:function(viewName)
{var redirectUrl=this.getViewUrl(viewName);this.redirectToUrl(redirectUrl);},redirectToUrl:function(redirectUrl)
{window.location=redirectUrl;}});

PWF.create('PWF.ActionWidget',PWF.Widget,{createAction:function(actionName,callbackInit,callbackSuccess,callbackFailure,method)
{var actionUrl=this.getActionUrl(actionName);return this.createActionByUrl(actionUrl,callbackInit,callbackSuccess,callbackFailure,method);},createActionByUrl:function(actionUrl,callbackInit,callbackSuccess,callbackFailure,method)
{return new PWF.Action(actionUrl,callbackInit.bind(this),callbackSuccess.bind(this),callbackFailure.bind(this),method);},getActionUrl:function(actionName)
{return this.getWidgetUrl()+'../../actions/'+actionName;}});

PWF.create('PWF.SingleActionWidget',PWF.ActionWidget,{onInternalInit:function()
{this.showLoadingAnimation();},onInternalSuccess:function(json)
{this.hideLoadingAnimation();this.onActionSuccess(json);},onInternalFailure:function(errorMsg,json)
{this.hideLoadingAnimation();this.onActionFailure(errorMsg,json);},setActionName:function(actionName)
{this.action=this.createAction(actionName,this.onInternalInit,this.onInternalSuccess,this.onInternalFailure);},setActionUrl:function(actionUrl)
{this.action=this.createActionByUrl(actionUrl,this.onInternalInit,this.onInternalSuccess,this.onInternalFailure);},clearActionParameters:function()
{this.action.clearParameters();},addActionParameter:function(key,value)
{this.action.addParameter(key,value);},runAction:function()
{this.action.run();},onActionSuccess:function(json)
{},onActionFailure:function(errorMsg)
{}});
